#include "cslepui.h"
#include "cslep.h"
#include "slepbase.h"
#include <QtGui>

void CSLEPUI::setupActions(){
	actionExit = new QAction(tr("Exit"),this);
	connect(actionExit, SIGNAL(triggered()), this, SLOT(close()));
	actionAddFiles = new QAction(tr("Add Files"),this);
	actionAbout = new QAction(tr("About CSLEP"),this);
	connect(actionAbout,SIGNAL(triggered()),this,SLOT(about()));

	actionLeastR = new QAction(tr("Least Squares loss"),this);
	connect(actionLeastR,SIGNAL(triggered()),this,SLOT(actLeastR()));
	actionNnLeastR = new QAction(tr("Least Squares loss (Non-negative Solution)"),this);
	connect(actionNnLeastR,SIGNAL(triggered()),this, SLOT(actnnLeastR()));
	actionLogisticR = new QAction(tr("Logistic loss"),this);
	connect(actionLogisticR, SIGNAL(triggered()), this, SLOT(actLogisticR()));
	actionNnLogisticR = new QAction(tr("Logistic loss (Non-negative Solution)"),this);
	connect(actionNnLogisticR, SIGNAL(triggered()), this, SLOT(actnnLogisticR()));

	actionLeastC = new QAction(tr("Least Squares loss"),this);
	connect(actionLeastC,SIGNAL(triggered()),this, SLOT(actLeastC()));
	actionNnLeastC = new QAction(tr("Least Squares loss (Non-negative Solution)"),this);
	connect(actionNnLeastC,SIGNAL(triggered()),this, SLOT(actnnLeastC()));
	actionLogisticC = new QAction(tr("Logistic loss"),this);
	connect(actionLogisticC,SIGNAL(triggered()),this, SLOT(actLogisticC()));
	actionNnLogisticC = new QAction(tr("Logistic loss (Non-negative Solution)"),this);
	connect(actionNnLogisticC,SIGNAL(triggered()),this, SLOT(actnnLogisticC()));


	actionLq1GlLeastR = new QAction(tr("Group Lasso (Least Squares loss)"),this);
	connect(actionLq1GlLeastR,SIGNAL(triggered()),this, SLOT(actglLeastR()));
	actionLq1GlLogisticR = new QAction(tr("Group Lasso (Logistic loss)"),this);
	connect(actionLq1GlLogisticR, SIGNAL(triggered()),this,SLOT(actglLogisticR()));
	actionLq1McLeastR = new QAction(tr("Multi-class(task) learning (Least Squares loss)"),this);
	actionLq1McLogisticR = new QAction(tr("Multi-class(task) learning (Logistic loss)"),this);
	actionLq1MtLeastR = new QAction(tr("Multi-task learning (Least Squares loss)"),this);
	actionLq1MtLogisticR = new QAction(tr("Multi-task learning (Logistic loss)"),this);

	actionL21McLeastC = new QAction(tr("Multi-class(task) learning (Least Squares loss)"),this);
	actionL21McLogisticC = new QAction(tr("Multi-class(task) learning (Logistic loss)"),this);
	actionL21MtLeastC = new QAction(tr("Multi-task learning (Least Squares loss)"),this);
	actionL21MtLogisticC = new QAction(tr("Multi-task learning (Logistic loss)"),this);

	actionFusedLasso = new QAction(tr("Fused Lasso with Least Squares loss"),this);
}


void CSLEPUI::setupMenus(){
	menuFile = menuBar()->addMenu(tr("&File"));
	menuFile->addAction(actionAddFiles);
	menuFile->addAction(actionExit);


	menuSolve = menuBar()->addMenu(tr("&Solve"));

	menuSolve->addAction(actionFusedLasso);
	menuL1Regularized = menuSolve->addMenu(tr("L1 Regularized"));
	menuL1Regularized->addAction(actionLeastR);
	menuL1Regularized->addAction(actionNnLeastR);
	menuL1Regularized->addAction(actionLogisticR);
	menuL1Regularized->addAction(actionNnLogisticR);

	menuL1Constrained = menuSolve->addMenu(tr("L1 Constrained"));
	menuL1Constrained->addAction(actionLeastC);
	menuL1Constrained->addAction(actionNnLeastC);
	menuL1Constrained->addAction(actionLogisticC);
	menuL1Constrained->addAction(actionNnLogisticC);

	menuLq1Regularized = menuSolve->addMenu(tr("Lq/L1 Regularized"));
	menuLq1Regularized->addAction(actionLq1GlLeastR);
	menuLq1Regularized->addAction(actionLq1GlLogisticR);
	menuLq1Regularized->addAction(actionLq1McLeastR);
	menuLq1Regularized->addAction(actionLq1McLogisticR);
	menuLq1Regularized->addAction(actionLq1MtLeastR);
	menuLq1Regularized->addAction(actionLq1MtLogisticR);

	menuL21Constrained = menuSolve->addMenu(tr("L2/L1 Constrained"));
	menuL21Constrained->addAction(actionL21McLeastC);
	menuL21Constrained->addAction(actionL21McLogisticC);
	menuL21Constrained->addAction(actionL21MtLeastC);
	menuL21Constrained->addAction(actionL21MtLogisticC);

	menuView = menuBar()->addMenu(tr("&View"));

	menuHelp = menuBar()->addMenu(tr("&Help"));
	menuHelp->addAction(actionAbout);

}



void CSLEPUI::setupWorkspacePanel(){
        dockWidget = new QDockWidget(tr("Workspace"),this);
        fileTable = new SLEPFileTable(this);
        slepItemList = fileTable->getSlepItemList();
        itemModel = fileTable->getItemModel();
        dockWidget->setWidget(fileTable);
        dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
        addDockWidget(Qt::RightDockWidgetArea, dockWidget);
        menuView->addAction(dockWidget->toggleViewAction());
}


void CSLEPUI::setupLogger(){
        loggerDock = new QDockWidget(tr("Output Log"),this);
		logger = LogWidget::instance();
        loggerDock->setWidget(logger);
        loggerDock->setAllowedAreas(Qt::BottomDockWidgetArea);
        addDockWidget(Qt::BottomDockWidgetArea, loggerDock);
        menuView->addAction(loggerDock->toggleViewAction());

}

void CSLEPUI::actLeastR(){
	optsWidget = new SlepOptionsWidget(Method_Least_R);
	LogWidget::instance()->log(QString("Executing Least R"));
	int success = optsWidget->exec();
	if(success == QDialog::Accepted){
		OPTS *opts = optsWidget->getOPTS();
		slep_matrix* A = optsWidget->getInputA();
		slep_vector* y = optsWidget->getInputy();
		slep_vector* x = slepAllocDenseVector(A->n);
		slep_vector* funVal = slepAllocDenseVector(opts->maxIter);
		slep_vector* valueL = slepAllocDenseVector(opts->maxIter);

		LeastR(A,y,optsWidget->getL1RegCoefficient(),opts,x,funVal,valueL);
		LogWidget::instance()->log(QString("Success executing Least R"));

		SLEPItem *itemA = SLEPFileOperations::slepMatrix2SlepItem(A);
		SLEPItem *itemy = SLEPFileOperations::slepVector2SlepItem(y);
		SLEPItem *itemx = SLEPFileOperations::slepVector2SlepItem(x);
		SLEPItem *itemFVal = SLEPFileOperations::slepVector2SlepItem(funVal);

        if(itemA->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("A");
			SLEPFileOperations::writeTextFile(*itemA,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemA);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemA->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemy->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("y");
			SLEPFileOperations::writeTextFile(*itemy,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemy);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemy->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemx->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("x");
			SLEPFileOperations::writeTextFile(*itemx,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemx);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemx->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
        if(itemFVal->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("fVal");
			SLEPFileOperations::writeTextFile(*itemFVal,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemFVal);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemFVal->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
		slepFreeMatrix(A);
		slepFreeVector(x);
		slepFreeVector(y);
		slepFreeVector(funVal);
		slepFreeVector(valueL);
		QMessageBox::information(this,tr("Success"), tr("It was run successfully!"));
	}
	else{
		QMessageBox::information(this,tr("Error"), tr("Was not able to execute as there were errors in input!"));
	}
	delete optsWidget;
}




void CSLEPUI::actnnLeastR(){
	optsWidget = new SlepOptionsWidget(Method_nnLeast_R);
	int success = optsWidget->exec();
	if(success == QDialog::Accepted){
		OPTS *opts = optsWidget->getOPTS();
		slep_matrix* A = optsWidget->getInputA();
		slep_vector* y = optsWidget->getInputy();
		slep_vector* x = slepAllocDenseVector(A->n);
		slep_vector* funVal = slepAllocDenseVector(opts->maxIter);
		slep_vector* valueL = slepAllocDenseVector(opts->maxIter);

		nnLeastR(A,y,optsWidget->getL1RegCoefficient(),opts,x,funVal,valueL);

		SLEPItem *itemA = SLEPFileOperations::slepMatrix2SlepItem(A);
		SLEPItem *itemy = SLEPFileOperations::slepVector2SlepItem(y);
		SLEPItem *itemx = SLEPFileOperations::slepVector2SlepItem(x);
		SLEPItem *itemFVal = SLEPFileOperations::slepVector2SlepItem(funVal);

        if(itemA->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("A");
			SLEPFileOperations::writeTextFile(*itemA,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemA);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemA->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemy->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("y");
			SLEPFileOperations::writeTextFile(*itemy,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemy);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemy->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemx->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("x");
			SLEPFileOperations::writeTextFile(*itemx,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemx);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemx->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
        if(itemFVal->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("fVal");
			SLEPFileOperations::writeTextFile(*itemFVal,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemFVal);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemFVal->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
		slepFreeMatrix(A);
		slepFreeVector(x);
		slepFreeVector(y);
		slepFreeVector(funVal);
		slepFreeVector(valueL);
		QMessageBox::information(this,tr("Success"), tr("It was run successfully!"));
	}
	else{
		QMessageBox::information(this,tr("Error"), tr("Was not able to execute as there were errors in input!"));
	}
	delete optsWidget;
}



void CSLEPUI::actLeastC(){
	optsWidget = new SlepOptionsWidget(Method_Least_C);
	int success = optsWidget->exec();
	if(success == QDialog::Accepted){
		OPTS *opts = optsWidget->getOPTS();
		slep_matrix* A = optsWidget->getInputA();
		slep_vector* y = optsWidget->getInputy();
		slep_vector* x = slepAllocDenseVector(A->n);
		slep_vector* funVal = slepAllocDenseVector(opts->maxIter);
		slep_vector* valueL = slepAllocDenseVector(opts->maxIter);

		LeastC(A,y,optsWidget->getL1RegCoefficient(),opts,x,funVal,valueL);

		SLEPItem *itemA = SLEPFileOperations::slepMatrix2SlepItem(A);
		SLEPItem *itemy = SLEPFileOperations::slepVector2SlepItem(y);
		SLEPItem *itemx = SLEPFileOperations::slepVector2SlepItem(x);
		SLEPItem *itemFVal = SLEPFileOperations::slepVector2SlepItem(funVal);

        if(itemA->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("A");
			SLEPFileOperations::writeTextFile(*itemA,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemA);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemA->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemy->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("y");
			SLEPFileOperations::writeTextFile(*itemy,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemy);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemy->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemx->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("x");
			SLEPFileOperations::writeTextFile(*itemx,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemx);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemx->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
        if(itemFVal->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("fVal");
			SLEPFileOperations::writeTextFile(*itemFVal,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemFVal);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemFVal->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
		slepFreeMatrix(A);
		slepFreeVector(x);
		slepFreeVector(y);
		slepFreeVector(funVal);
		slepFreeVector(valueL);
		QMessageBox::information(this,tr("Success"), tr("It was run successfully!"));
	}
	else{
		QMessageBox::information(this,tr("Error"), tr("Was not able to execute as there were errors in input!"));
	}
	delete optsWidget;
}



void CSLEPUI::actnnLeastC(){
	optsWidget = new SlepOptionsWidget(Method_nnLeast_C);
	int success = optsWidget->exec();
	if(success == QDialog::Accepted){
		OPTS *opts = optsWidget->getOPTS();
		slep_matrix* A = optsWidget->getInputA();
		slep_vector* y = optsWidget->getInputy();
		slep_vector* x = slepAllocDenseVector(A->n);
		slep_vector* funVal = slepAllocDenseVector(opts->maxIter);
		slep_vector* valueL = slepAllocDenseVector(opts->maxIter);

		nnLeastC(A,y,optsWidget->getL1RegCoefficient(),opts,x,funVal);

		SLEPItem *itemA = SLEPFileOperations::slepMatrix2SlepItem(A);
		SLEPItem *itemy = SLEPFileOperations::slepVector2SlepItem(y);
		SLEPItem *itemx = SLEPFileOperations::slepVector2SlepItem(x);
		SLEPItem *itemFVal = SLEPFileOperations::slepVector2SlepItem(funVal);

        if(itemA->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("A");
			SLEPFileOperations::writeTextFile(*itemA,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemA);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemA->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemy->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("y");
			SLEPFileOperations::writeTextFile(*itemy,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemy);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemy->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}

        if(itemx->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("x");
			SLEPFileOperations::writeTextFile(*itemx,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemx);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemx->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
        if(itemFVal->type != SLEPItem::NONE){
			QStandardItemModel* itemModel = fileTable->getItemModel();
			QList<SLEPItem>* slepItemList = fileTable->getSlepItemList();
			QString fileName("fVal");
			SLEPFileOperations::writeTextFile(*itemFVal,fileName);
            itemModel->insertRow(0);
            slepItemList->insert(0,*itemFVal);
            itemModel->setData(itemModel->index(0,0),QFileInfo(fileName).baseName());
            itemModel->setData(itemModel->index(0,1),QString(SLEPItem::TYPES_LONG[slepItemList->at(0).type]));
            itemModel->setData(itemModel->index(0,2),itemFVal->info());
			itemModel->setData(itemModel->index(0,3),QFileInfo(fileName).canonicalFilePath());
		}
		slepFreeMatrix(A);
		slepFreeVector(x);
		slepFreeVector(y);
		slepFreeVector(funVal);
		slepFreeVector(valueL);
		QMessageBox::information(this,tr("Success"), tr("It was run successfully!"));
	}
	else{
		QMessageBox::information(this,tr("Error"), tr("Was not able to execute as there were errors in input!"));
	}
	delete optsWidget;
}